import patchVnode from "./patchVnode";
import createElement from "./createElement";

function checkSame(a, b){
    return (a.sel == b.sel && a.key == b.key)
}
export default function updateChildren(parElm, newCh, oldCh) {
    // 指针
    // 新前
    let newStartIdx = 0
    // 新后
    let newEndIdx = newCh.length - 1
    // 旧前
    let oldStartIdx = 0
    // 旧后
    let oldEndIdx = oldCh.length - 1

    //新前节点
    let newStartVNode = newCh[newStartIdx]
    // 旧前节点
    let oldStartVNode = oldCh[oldStartIdx]
    // 新后节点
    let newEndVNode = newCh[newEndIdx]
    // 旧后节点
    let oldEndVNode = oldCh[oldEndIdx]
    // 设置keyMap,遍历使用
    let keyMap = null

    while(newStartIdx <= newEndIdx && oldStartIdx <= oldEndIdx){
        if(newStartVNode == null || newCh[newStartIdx] == undefined){
            newStartVNode = newCh[++newStartIdx]
        } else if (newEndVNode == null || newCh[newEndIdx] == undefined) {
            newEndVNode = newCh[--newEndIdx]
        } else if (oldStartVNode == null || oldCh[oldStartIdx] == undefined) {
            oldStartVNode = oldCh[++oldStartIdx]
        } else if (oldEndVNode == null || oldCh[oldEndIdx] == undefined) {
            oldEndVNode = oldCh[--oldEndIdx]
        }
        // 新前与旧前对比--如果相同
        else if(checkSame(oldStartVNode,newStartVNode,)) {
            console.log('这是前前命中')
            patchVnode(oldStartVNode, newStartVNode)    // 相同节点开始对比差异并更新节点
            newStartVNode = newCh[++newStartIdx] // 新前指针下移
            oldStartVNode = oldCh[++oldStartIdx] // 旧前指针下移
        }
        // 新后与旧后对比
        else if (checkSame(oldEndVNode, newEndVNode)) {
            console.log('这是后后命中')
            patchVnode(oldEndVNode, newEndVNode)
            newEndVNode = newCh[--newEndIdx] // 新后向上移
            oldEndVNode = oldCh[--oldEndIdx] // 旧后向上移
        }

        // 新后与旧前对比
        else if(checkSame(newEndVNode, oldStartVNode )){
            console.log('这是新后与旧前命中')
            patchVnode(oldStartVNode, newEndVNode)
            parElm.insertBefore(oldStartVNode.elm,oldEndVNode.elm.nextSibling)  // 移动到旧后节点下一个节点之前
            oldStartVNode = oldCh[++oldStartIdx] // 旧前向下移动
            newEndVNode = newCh[--newEndIdx] // 新后向上移动
        }

        // 新前与旧后对比
        else if(checkSame(newStartVNode,oldEndVNode)){
            console.log('这是新前与旧后命中')
            patchVnode(newStartVNode,oldEndVNode)
            parElm.insertBefore(oldEndVNode.elm,oldStartVNode.elm)  // 移动到旧起始节点之前
            oldEndVNode = oldCh[--oldEndIdx] // 旧后向上移动
            newStartVNode = newCh[++newStartIdx] // 新前向下移动
        }
        else {
            console.log(oldStartVNode[oldStartIdx], '四种都没命中')
            if(!keyMap){
                keyMap = {}
                for (let i = oldStartIdx; i <= oldEndIdx; i++ ){
                    const key = oldCh[i].key
                    if(key) {
                        keyMap[key] = i
                    }
                }
            }
            // 寻找到新前当前在旧节点中的位置
            const idxInOld = keyMap[newStartVNode.key]
            console.log('idxInOld',idxInOld)
            if(idxInOld) {
                // 只是移动
                // 获取当前移动节点
                const elmToMove = oldCh[idxInOld]
                // 比较当前节点与新节点的变化
                patchVnode(elmToMove,newStartVNode)
                // 将旧节点当前项设置为undefined
                //开始移动--将此子节点移动到旧前之前
                parElm.insertBefore(elmToMove.elm, oldStartVNode.elm)
                oldCh[idxInOld] = null
            } else {
                // 新增的项--在旧前节点加
                parElm.insertBefore(createElement(newStartVNode), oldStartVNode.elm)
            }
            newStartVNode = newCh[++newStartIdx];
        }
    }

    // 新增情况
    if(newStartIdx <= newEndIdx) {
        console.log('这是新增')
        // 这是插入的标杆
        for (let i = newStartIdx; i <= newEndIdx; i++ ) {
            parElm.insertBefore(createElement(newCh[i]),oldCh[oldStartIdx] ? oldCh[oldStartIdx].elm : null)
        }
    }
    // 删除情况
    else if (oldStartIdx <= oldEndIdx) {
        console.log('这是删除')
        for(let i = oldStartIdx; i <= oldEndIdx; i++ ) {
            if(oldCh[i]){
                parElm.removeChild(oldCh[i].elm)
            }
        }
    }
}
